﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Timers;
using Reborn_WorldServer;
using System.Drawing;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_RaiseCorpses : AreaSpell
    {
        private string castingFaction = "";

        public Spell_RaiseCorpses() { }

        public override bool hasCustomTarget(SpellIcon sIcon)
        {
            return true;
        }


        private int choosenMapX = -1;
        private int choosenMapY = -1;
        public override bool hasValidTarget(SpellIcon sIcon, Creature creature, List<Point> hiddenList)
        {
            MapItem choosenTile = null;
            int numCorpses = 0;
            foreach (MapItem mapitem in creature.currentMapItem.mapItemsWithin4)
            {
                if (CreatureAI.isHidden(mapitem.MapX, mapitem.MapY, hiddenList) == false && mapitem.Motion > 0)
                {
                    if (mapitem.ContainsSpellByStackType(sIcon.StackType))
                        continue;

                    int corpsesOnTile = mapitem.parentMap.LootMngr.getNumCorpses(mapitem.MapX, mapitem.MapY);
                    if (corpsesOnTile > numCorpses)
                    {
                        choosenTile = mapitem;
                        numCorpses = corpsesOnTile;
                    }
                }
            }

            if (choosenTile != null)
            {
                choosenMapX = choosenTile.MapX;
                choosenMapY = choosenTile.MapY;
                return true;
            }

            return false;
        }

        public void PositionCast(SpellIcon _spellIcon, CreatureBase myCreatureBase, int CastLevel, int MapX, int MapY)
        {
            if (choosenMapX != -1 && choosenMapY != -1)
            {
                MapX = choosenMapX;
                MapY = choosenMapY;
            }

            List<MapItem> MapItemsWithin12;
            base.InitializeInstantCast(myCreatureBase, CastLevel, _spellIcon, MapX, MapY, out MapItemsWithin12);


            MainCast(myCreatureBase, CastMapX, CastMapY, MapItemsWithin12);
        }

        private void MainCast(CreatureBase myCreatureBase, int MapX, int MapY, List<MapItem> MapItemsWithin12)
        {
            castingFaction = myCreatureBase.Faction;
            spellTimer.Interval = 2000;

            List<Character> CharactersWithin8 = new List<Character>();
            MapItem CurrentMapItem = null;

            foreach (MapItem mapitem in MapItemsWithin12)
            {
                if (Math.Abs(mapitem.MapX - CastMapX) <= 8 && Math.Abs(mapitem.MapY - CastMapY) <= 8)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character)
                            CharactersWithin8.Add((Character)creaturebase);
                    }
                }
                if (mapitem.MapX == CastMapX && mapitem.MapY == CastMapY)
                    CurrentMapItem = mapitem;
            }
            CurrentMapItem.SpellLayer0.Add(this);
            MapItems.Add(CurrentMapItem);

            foreach (Character character in CharactersWithin8)
            {
                character.AddMapItem(CurrentMapItem);
                character.PlaySound("RaiseCorpses", CastMapX, CastMapY);
            }

            spellTimer.Start();
        }

        public void Cast(CreatureBase myCreatureBase, int CastLevel, List<string> MoveList)
        {
            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, MoveList, out MapItemsWithin12) == false)
                return;

            MainCast(myCreatureBase, CastMapX, CastMapY, MapItemsWithin12);
        }
        protected override void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            TimerCounter = TimerCounter + 1;

            LockItem lockItem = Managers.GameHandler.GetLockItem(MapID, Instance);
            lock (lockItem.LockObj)
            {
                bool foundSpell = false;
                foreach (Spell spell in CastMapItem.SpellLayer0)
                {
                    if (spell.SpellID == SpellID)
                    {
                        foundSpell = true;
                        break;
                    }
                }
                if (foundSpell == false)
                    return;

                Map CurrentMap = Managers.GameHandler.GetMap(MapID, Instance);
                List<Character> CharactersWithin8 = new List<Character>();
                foreach (MapItem mapitem in CastMapItem.mapItemsWithin4)
                {
                    foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                    {
                        if (creaturebase is Character)
                            CharactersWithin8.Add((Character)creaturebase);
                    }
                }
                bool updateMapItem = false;
                bool corpseSpawned = false;
                Corpse corpse = CurrentMap.LootMngr.TakeFirstCreatureCorpse(CastMapX, CastMapY);
                if (corpse != null)
                {
                    CreatureSpawn spawn = new CreatureSpawn(Managers.GameHandler);
                    spawn.MaxHPBase = SkillManager.AdjustForCombat(CastingCreatureLevel, 0, CastingCreatureWis / 2) * 5;
                    spawn.HP = spawn.MaxHPBase;
                    spawn.MaxStaminaBase = 1000;
                    spawn.Stamina = 1000;

                    spawn.MaxManaBase = 0;
                    spawn.Mana = 0;

                    spawn.Agility = 3 * CastingCreatureLevel;
                    spawn.Armor = SkillManager.AdjustForCombat(CastingCreatureLevel, 0, CastingCreatureWis / 2);
                    spawn.ResistHoly = CastingCreatureLevel + (CastingCreatureWis / 5);
                    spawn.ResistUnholy = CastingCreatureLevel * 7 + (CastingCreatureWis);
                    spawn.ResistMagic = CastingCreatureLevel * 2 + (CastingCreatureWis);
                    spawn.ResistFire = CastingCreatureLevel * 2 + (CastingCreatureWis);
                    spawn.ResistIce = CastingCreatureLevel * 2 + (CastingCreatureWis);
                    spawn.ResistPhysical = CastingCreatureLevel * 2 + (CastingCreatureWis);

                    spawn.Dexterity = CastingCreatureInt / 2;
                    spawn.Strength = CastingCreatureInt / 2;
                    spawn.Wisdom = 0;
                    spawn.Intelligence = 0;

                    spawn.Defense = CastingCreatureWis / 2;
                    spawn.DefenseSkill = CastingCreatureLevel;
                    //iceGolem.HandBlockWeapon = "icy fist";

                    spawn.RushAttack = true;
                    spawn.Water = true;
                    spawn.Air = false;
                    spawn.Land = true;

                    CreatureAttackWeapon iceGolemWeapon = new CreatureAttackWeapon();
                    iceGolemWeapon.Accuracy = CastingCreatureInt;
                    iceGolemWeapon.Description = "claws {name}";
                    iceGolemWeapon.DmgHigh = CastingCreatureInt + 10;
                    iceGolemWeapon.DmgLow = CastingCreatureInt - 10;
                    iceGolemWeapon.Frequency = 1;
                    iceGolemWeapon.Sequence = 1;
                    iceGolemWeapon.SkillLevel = CastingCreatureLevel;
                    iceGolemWeapon.Speed = 3.1M;

                    spawn.attackSequenceManager.Attacks.Add(iceGolemWeapon);

                    spawn.Name = "Re-Animated Corpse";
                    spawn.SoundDeath = "SpiderDeath";

                    //No corpse image will cause DropLoot() to not generate a corpse
                    spawn.CorpseImageURL = "";

                    spawn.CreatureID = Managers.GameHandler.ItemIDGen.GetCreatureUID();
                    spawn.CreatureType = "Creature";
                    spawn.Faction = this.castingFaction;
                    spawn.ID = -1;
                    spawn.ImageURL = "ReanimatedCorpse";
                    spawn.Instance = Instance;
                    spawn.MapID = MapID;
                    spawn.StartMapID = MapID;
                    spawn.WanderMax_E = CastMapX + 4;
                    spawn.WanderMax_W = CastMapX - 4;
                    spawn.WanderMax_N = CastMapY - 4;
                    spawn.WanderMax_S = CastMapY + 4;
                    spawn.StartMapX = CastMapX;
                    spawn.StartMapY = CastMapY;

                    spawn.MaxMoves = 4;

                    spawn.LootItems = corpse.LootToDrop;
                    spawn.isCorpseLoot = true;

                    spawn.SetPosition(CastMapItem);
                    CastMapItem.CreaturesBases.Add(spawn);

                    spawn.creatureAI.Timer_CreatureRound.Start();
                    spawn.Timer_Regen.Start();
                    spawn.StartLifespanTimer(180);

                    updateMapItem = true;
                    corpseSpawned = true;
                }
                if (TimerCounter > 2)
                {
                    CastMapItem.SpellLayer0.Remove(this);
                    updateMapItem = true;
                }
                else
                {
                    spellTimer.Start();
                }
                if (updateMapItem == true)
                {
                    foreach (Character character in CharactersWithin8)
                    {
                        character.AddMapItem(CastMapItem);

                        if (corpseSpawned == true)
                            character.PlaySound("SpawnCorpse", CastMapX, CastMapY);
                    }
                }
            }
        }
    }
}
